<template>
	<div class="print-template-detail">
		<div class="print-template-detail__body">
			<div class="system-view-nav" style="width:310px;">
				<el-scrollbar class="left-scrollbar">
					<el-card shadow="never" :body-style="{ padding: '0px 0 5px 7px' }">
						<el-row>
							<el-col :span="24" id="hiprintEpContainer" class="rect-printElement-types hiprintEpContainer"> </el-col>
						</el-row>
					</el-card>
				</el-scrollbar>
			</div>
			<div class="system-view-content">
				<div class="head">
					<div class="head_actions head_left">
						<div class="head_btn" @click="openPageSize()">
							<el-tooltip content="纸张大小" placement="top-start">
								<i class="icon-ym icon-ym-orderExample" />
							</el-tooltip>
						</div>
						<div class="tool-item-line" />
						<div class="head_btn" @click="clearPaper()">
							<el-tooltip content="清空" placement="top-start">
								<i class="icon-ym icon-ym-clean" style="color: red" />
							</el-tooltip>
						</div>
						<div class="tool-item-line" />
						<div class="head_btn" @click="handleUndo()">
							<el-tooltip content="撤销" placement="top-start">
								<i class="icon-ym icon-ym-report-icon-undo" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="handleRedo()">
							<el-tooltip content="重做" placement="top-start">
								<i class="icon-ym icon-ym-report-icon-restore" />
							</el-tooltip>
						</div>
						<div class="tool-item-line" />
						<div class="head_btn" @click="rotatePaper()">
							<el-tooltip content="旋转" placement="top-start">
								<i class="icon-ym icon-ym-btn-refresh" />
							</el-tooltip>
						</div>
						<div class="tool-item-line" />
						<div class="head_btn" @click="setElsAlign('left')">
							<el-tooltip content="左对齐" placement="top-start">
								<i class="icon-ym icon-ym-report-icon-align-left" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="setElsAlign('vertical')">
							<el-tooltip content="居中" placement="top-start">
								<i class="icon-ym icon-ym-report-icon-align-center" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="setElsAlign('right')">
							<el-tooltip content="右对齐" placement="top-start">
								<i class="icon-ym icon-ym-report-icon-align-right" />
							</el-tooltip>
						</div>
						<div class="tool-item-line" />
						<div class="head_btn" @click="setElsAlign('top')">
							<el-tooltip content="顶部对齐" placement="top-start">
								<i class="icon-ym icon-ym-report-icon-align-top" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="setElsAlign('horizontal')">
							<el-tooltip content="垂直居中" placement="top-start">
								<i class="icon-ym icon-ym-report-icon-align-middle" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="setElsAlign('bottom')">
							<el-tooltip content="底部对齐" placement="top-start">
								<i class="icon-ym icon-ym-report-icon-align-bottom" />
							</el-tooltip>
						</div>
						<div class="tool-item-line" />
						<div class="head_btn" @click="changeScale(false)">
							<el-tooltip content="缩小" placement="top-start">
								<i class="ym-custom ym-custom-minus" />
							</el-tooltip>
						</div>
						<span style="font-size: 18px">{{ state.scaleValue }}%</span>
						<div class="head_btn" @click="changeScale(true)">
							<el-tooltip content="放大" placement="top-start">
								<i class="ym-custom ym-custom-plus" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="restore()">
							<el-tooltip content="还原" placement="top-start">
								<i class="ym-custom ym-custom-restore" />
							</el-tooltip>
						</div>
						<div class="tool-item-line" />
						<div class="head_btn" @click="setElsAlign('distributeHor')">
							<el-tooltip content="横向分散" placement="top-start">
								<i class="ym-custom ym-custom-swap-horizontal" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="setElsAlign('distributeVer')">
							<el-tooltip content="纵向分散" placement="top-start">
								<i class="ym-custom ym-custom-swap-vertical" />
							</el-tooltip>
						</div>
						<div class="tool-item-line" />
						<div class="head_btn" @click="viewJson()">
							<el-tooltip content="模板JSON" placement="top-start">
								<i class="ym-custom ym-custom-json" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="preView()">
							<el-tooltip content="预览" placement="top-start">
								<i class="ym-custom ym-custom-eye" />
							</el-tooltip>
						</div>
						<div class="head_btn" @click="print()">
							<el-tooltip content="打印" placement="top-start">
								<i class="ym-custom ym-custom-printer" />
							</el-tooltip>
						</div>
					</div>
				</div>
				<el-scrollbar class="left-scrollbar">
					<div id="templateDesignDiv" class="hiprint-printTemplate" style="padding:24px;"></div>
				</el-scrollbar>
			</div>
			<div class="system-view-nav" style="margin-left: 10px;margin-right: 0;">
				<el-scrollbar class="left-scrollbar">
					<el-card shadow="never" :body-style="{ padding: '0px' }">
						<el-row class="hinnn-layout-sider">
							<div id="PrintElementOptionSetting"></div>
						</el-row>
					</el-card>
				</el-scrollbar>
			</div>
		</div>
		<PageSize ref="pageSizeRef" title="页面设置" @change="getEditConfig" />
	</div>

	<el-drawer content="打印模板" v-model="state.templateDialogVisible">
		<vue-json-pretty :data="state.templateContent" showLength showIcon showLineNumber showSelectController />
	</el-drawer>

	<!-- 预览 -->
	<PrintPreview ref="preViewRef" />
</template>

<script lang="ts" setup name="hiprintDesign">
// import $ from 'jquery';
import { computed, onMounted, ref, reactive, watch } from 'vue';
import { ElMessage, ElMessageBox } from 'element-plus';
import VueJsonPretty from 'vue-json-pretty';
import 'vue-json-pretty/lib/styles.css';

import { hiprint, defaultElementTypeProvider } from 'vue-plugin-hiprint';
import PrintPreview from './preview.vue';
import PageSize from './pageSize.vue';
import helper from './provider-helper.js';
import internal from 'stream';
import { fa } from 'element-plus/es/locale';

const emit = defineEmits(["input"]);


let hiprintTemplate = ref();

const preViewRef = ref();
const pageSizeRef = ref();


interface State {
	inputFileTarget: any;
	template: any;
	scaleValue: number;
	scaleMax: number;
	scaleMin: number;
	printTemplate: any;
	hiprintTemplate: any;
	pageParam: any;
	fileds: any;
	curPaper: any;
	templateContent: any;
	templateDialogVisible: boolean;
}
const props = defineProps({
	value: { type: String, default: '' },
	treeData: { type: Array, default: () => [] },
});

const state = reactive<State>({
	templateDialogVisible: false,
	templateContent: '',
	inputFileTarget: {},
	template: null,
	// 当前纸张
	curPaper: {
		type: 'A4',
		width: 220,
		height: 296.6,
	},
	scaleValue: 100,
	scaleMax: 500,
	scaleMin: 50,
	printTemplate: {
		panels: [
			{
				index: 0,
				width: 100,
				height: 80,
				paperHeader: 0,
				paperFooter: 0,
				printElements: [],
				paperNumberLeft: 0,
				paperNumberTop: 0,
				paperNumberDisabled: true,
			},
		],
	},
	hiprintTemplate: {},
	pageParam: {},
	fileds: [],
});

function getTreeData() {
	const list = props.treeData || [];
	const loop = (dataList: any) => {
		for (let i = 0; i < dataList.length; i++) {
			const element: any = dataList[i];
			element.newId = element.parentId + '_' + element.id;
			if (element.children?.length) loop(element.children);
		}
	};
	loop(list);
	return list;
}

/**
	 * 构建provider
	 * 注意: 可拖拽元素必须在 hiprint.init() 之后调用
	 * 调用之前 可以先 console.log($("#provider-container")) 看看是否有该 dom
	 */
const buildProvider = (data: any, clear: any) => {
	// 组装 provider
	if (Array.isArray(data)) {
		let providerList = helper.createProviderList(data);
		hiprint.init({ providers: providerList });
	} else {
		let provider = helper.createProvider(data.key, data.options);
		hiprint.init({ providers: [provider] });
	}
	if (clear) {
		$('.hiprintEpContainer').empty(); // 先清空, 避免重复构建
	}
	if (Array.isArray(data)) {
		data.forEach(item => hiprint.PrintElementTypeManager.build($('.hiprintEpContainer'), item.key));
	} else {
		hiprint.PrintElementTypeManager.build($('.hiprintEpContainer'), data.key);
	}
};

watch(
	() => props.value,
	newValue => {
		if (newValue != state.template) state.template = newValue;
	},
	{ immediate: true, deep: true },
);

watch(
	() => state.template,
	newValue => {
		emit('input', newValue);
	},
);

function init() {
	if (state.template) state.printTemplate = JSON.parse(state.template);

	hiprint.init({
		providers: [defaultElementTypeProvider()],
	});

	$('.hiprintEpContainer').empty();

	state.pageParam = {
		type: '1',
		width: state.printTemplate.panels[0].width,
		height: state.printTemplate.panels[0].height,
	};

	hiprint.PrintElementTypeManager.build('.hiprintEpContainer', 'defaultModule');

	state.hiprintTemplate = new hiprint.PrintTemplate({
		template: state.printTemplate,
		settingContainer: '#PrintElementOptionSetting',
		paginationContainer: '.hiprint-printPagination',

		onImageChooseClick: (e: any) => {
			state.inputFileTarget = e;
			$('#img_upload').click();
		},
		// 自定义可选字体
		// 或者使用 hiprintTemplate.setFontList([])
		// 或元素中 options.fontList: []
		fontList: [
			{ title: '微软雅黑', value: 'Microsoft YaHei' },
			{ title: '黑体', value: 'STHeitiSC-Light' },
			{ title: '思源黑体', value: 'SourceHanSansCN-Normal' },
			{ title: '王羲之书法体', value: '王羲之书法体' },
			{ title: '宋体', value: 'SimSun' },
			{ title: '华为楷体', value: 'STKaiti' },
			{ title: 'cursive', value: 'cursive' },
		],
		dataMode: 1, // 1:getJson 其他：getJsonTid 默认1
		history: true, // 是否需要 撤销重做功能
		willOutOfBounds: true, // 是否允许组件内的控件超出范围
		qtDesigner: true, // 是否开启类似QT Designer的唯一field生成模式
		onDataChanged: (type: any, json: any) => {
			console.log(type); // 新增、移动、删除、修改(参数调整)、大小、旋转
			console.log(json); // 返回 template

			state.template = JSON.stringify(state.hiprintTemplate.getJson());
			// this.$emit("saveTemplate", jsonInfo)
		},
		onUpdateError: (e: any) => {
			console.log(e);
		},
	});

	state.hiprintTemplate.design('#templateDesignDiv', { grid: true });

	// 获取当前放大比例, 当zoom时传true 才会有
	state.scaleValue = state.hiprintTemplate.editingPanel.scale || 100;
}

// 还原
const restore = () => {
	state.scaleValue = 100;
	state.hiprintTemplate.zoom(state.scaleValue / 100);
}

// 改变缩放比例
const changeScale = (big: boolean) => {
	let scaleValue = state.scaleValue;
	if (big) {
		scaleValue += 10;
		if (scaleValue > state.scaleMax) {
			scaleValue = 500;
			ElMessage.error(`最大只能放大到${state.scaleValue}%`);
		}
	} else {
		scaleValue -= 10;
		if (scaleValue < state.scaleMin) {
			scaleValue = 50;
			ElMessage.error(`最小只能缩放到${state.scaleValue}%`);
		}
	}
	if (state.hiprintTemplate) {
		// scaleValue: 放大缩小值, false: 不保存(不传也一样),如果传 true, 打印时也会放大
		state.hiprintTemplate.zoom(scaleValue / 100);
		state.scaleValue = scaleValue;
	}
}

// 旋转模板
const rotatePaper = () => {
	if (state.hiprintTemplate) {
		state.hiprintTemplate.rotatePaper();
	}
};

// 对齐模板
const setElsAlign = (e: any) => {
	hiprintTemplate.value.setElsAlign(e);
};

// 撤销
const handleUndo = () => {
	state.hiprintTemplate.undo();
}

// 重做
const handleRedo = () => {
	state.hiprintTemplate.redo();
}

// 清空模板
const clearPaper = () => {
	ElMessageBox.confirm('是否确认清空模板信息?', '警告', {
		confirmButtonText: '确定',
		cancelButtonText: '取消',
		type: 'warning',
	})
		.then(() => {
			try {
				state.hiprintTemplate.clear();
			} catch (error) {
				ElMessage.error(`操作失败: ${error}`);
			}
		})
		.catch((err) => {
			console.log(err);
		});
};

// 预览
const preView = () => {
	let { width } = state.printTemplate.panels[0];
	preViewRef.value.showDialog(state.hiprintTemplate, {}, width, 2);
};
// 直接打印
const print = () => {
	console.log('直接打印');
};

// 查看模板JSON
const viewJson = () => {
	if (state.hiprintTemplate) {
		var templateJson = JSON.stringify(state.hiprintTemplate.getJson() || {});
		state.templateContent = JSON.parse(templateJson);
		state.templateDialogVisible = true;
	}
};

const openPageSize = () => {
	pageSizeRef.value?.openDialog({ pageParam: state.pageParam });
}

const getEditConfig = (e: any) => {
	if (!e) {
		e = {};
		e.width = 210;
		e.height = 297;
	}

	let width = e.width ? e.width : 210;
	let height = e.height ? e.height : 297;
	setPaper(width, height);
}

//设置纸张大小
const setPaper = (paperTypeOrWidth: any, height: any) => {
	if (state.hiprintTemplate.setPaper) {
		state.pageParam = {
			width: paperTypeOrWidth,
			height: height,
		};
		state.hiprintTemplate.setPaper(paperTypeOrWidth, height);
	}
}

onMounted(() => {
	const dataList: any = getTreeData();

	for (let i = 0; i < dataList.length; i++) {
		const data: any = {
			key: '',
			tid: '',
			options: {
				groupName: '',
				printElements: [],
			},
		};
		data.key = dataList[i].newId;
		data.tid = 'defaultModule.' + dataList[i].newId;
		data.options.groupName = dataList[i].fullName;
		for (let j = 0; j < dataList[i].children.length; j++) {
			let ele = {
				id: dataList[i].children[j].newId,
				type: 'text',
				width: 150,
				height: 18.75,
				title: dataList[i].children[j].fullName,
				testData: `{#${dataList[i].children[j].fullName}}`,
				options: {
					hideTitle: true,
					zIndex: 666,
					field: dataList[i].children[j].fullName,
					color: '#000000',
					fontSize: 12,
					textAlign: 'center',
					textContentVerticalAlign: 'middle',
				},
			};
			data.options.printElements.push(ele);
		}
		state.fileds.push(data);
	}
	init();
	buildProvider(state.fileds, false);
});

// 导出对象
defineExpose({ hiprintTemplate });
</script>

<style lang="scss" scoped>
:deep(.hiprint-headerLine) {
	border-color: red !important;
}

:deep(.hiprint-footerLine) {
	border-color: red !important;
}

:deep(.hiprint-headerLine:hover:before) {
	content: '页眉线';
	left: calc(50% - 18px);
	position: relative;
	background: #ffff;
	top: -12px;
	color: red;
	font-size: 12px;
}

:deep(.hiprint-footerLine:hover:before) {
	content: '页脚线';
	left: calc(50% - 18px);
	position: relative;
	color: red;
	background: #ffff;
	top: -12px;
	font-size: 12px;
}

:deep(.hiprint-footerLine),
:deep(.hiprint-headerLine) {
	&:hover {
		border-top: 3px dashed red !important;
	}
}


:deep(.rect-printElement-types .hiprint-printElement-type > li > ul > li > a) {
	height: auto;
	text-overflow: ellipsis;
	color: var(--el-color-primary);
	box-shadow: none !important;
	border: 1px dashed var(--el-color-primary);
}

// 默认图片
:deep(.hiprint-printElement-image-content > img) {
	content: url('/@/assets/logo.png') !important;
}

// 设计容器
.card-design {
	overflow: hidden;
	overflow-x: auto;
	overflow-y: auto;
}

:deep(.hiprint-option-item-submitBtn) {
	background: var(--el-color-primary);
}

:deep(.hiprint-option-item-deleteBtn) {
	background: var(--el-color-danger);
}

:deep(.prop-tabs .prop-tab-items li.active) {
	color: var(--el-color-primary);
	border-bottom: 2px solid var(--el-color-primary);
}


.print-template-detail {
	height: 100%;
	display: flex;

	&__body {
		flex: 1;
		position: relative;
		display: flex;
		overflow: hidden;
	}
}

.system-view-nav {
	width: 300px;
	position: relative;
	background: #fff;
	margin-right: 10px;
	border-radius: 4px;
	overflow: hidden;

	.left-scrollbar {
		height: 100%;

		:deep(.el-scrollbar__wrap) {
			overflow-x: hidden;
		}
	}

	.Admin-common-title {
		padding: 0 10px;
		margin-bottom: 10px;
		height: 39px;

		&.sys-title {
			margin-top: 30px;
		}

		h2 {
			font-size: 14px;
			line-height: 39px;
			color: #043254;
			font-weight: bold;
		}
	}
}

.system-view-content {
	flex: 1;
	background: #fff;
	display: flex;
	flex-direction: column;
	overflow-x: auto;
	border-radius: 4px;

	:deep(.tox-tinymce) {
		border: none;
	}
}

.head {
	border-bottom: 1px solid #e6e6e6;
	display: flex;
	z-index: 100;
	align-items: center;
	user-select: none;

	&_actions {
		display: flex;
		justify-content: flex-end;
		align-items: center;
		height: 40px;
	}

	&_left {
		left: 8px;
		justify-content: flex-start;
	}

	&_btn {
		border-radius: 5px;
		margin-left: 4px;
		width: 34px;
		height: 34px;
		line-height: 34px;
		text-align: center;
		cursor: pointer;
		transition: 0.2s;

		i {
			color: #000;
			font-size: 24px;
		}

		&--active {
			background-color: #2681ff;
		}
	}

	&_info {
		position: absolute;
		left: 50%;
		top: 0;
		transform: translateX(-50%);
		text-align: center;
		cursor: default;
		font-size: 14px;
		max-width: 500px;
		font-weight: bold;
		color: #fff;
		line-height: 40px;
		overflow: hidden;
		text-overflow: ellipsis;
		white-space: nowrap;
		display: flex;
		align-items: center;

		i {
			margin-right: 8px;
			font-size: 20px;
		}
	}
}

.head_btn:hover {
	background-color: #dee0e2;
}

.tool-item-line {
	padding: 0;
	margin-left: 10px;
	margin-right: 10px;
	display: inline-block;
	height: 24px;
	line-height: 24px;
	border-left: 1px solid #e6e6e6;
}
</style>
